package MyList;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MyArrayListTest {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        MyArrayList<Integer> arrayList = new MyArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        System.out.println(arrayList);
    }
}

class MyArrayList<E> {
    //初始容量
    public static int intCapacity = 10;
    //初始化空的
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    //最大数组长度
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    //数组
    public Object[] elem;
    //有效的数据个数
    public int usedSize;

    public MyArrayList() {
        this.elem = new Object[intCapacity];
        this.usedSize = 0;
    }

    @Override
    public String toString() {
        return "MyArrayList{" +
                "elem=" + Arrays.toString(elem) +
                ", usedSize=" + usedSize +
                '}';
    }

    /**
     * 判断是否满了
     *
     * @return
     */
    private boolean isFull() {
        return usedSize == elem.length;
    }

    /**
     * 增加
     *
     * @param e
     */
    public boolean add(E e) {
        // 确保数组的容量能够装下新添加的元素，如果不够充足则进行扩容
        ensureCapacityInternal(usedSize + 1);  // Increments modCount!!
        elem[usedSize++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elem, minCapacity));
    }

    private static final int DEFAULT_CAPACITY = 10;
    // elem == DEFAULTCAPACITY_EMPTY_elem 判断elem 是否为空
    // 如果为空则此次添加元素是第一次添加元素，返回DEFAULT_CAPACITY
    // 否则返回minCapacity
    private static int calculateCapacity(Object[] elem, int minCapacity) {
        if (elem == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

    // minCapacity - elem.length > 0
    // 如果增加一个元素后的容量比现有的容量大，则使用grow进行扩容
    private void ensureExplicitCapacity(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elem.length > 0)
            grow(minCapacity);
    }

    // 扩容方法
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elem.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1); //  >> 表示除2，即扩容1.5倍
        if (newCapacity - minCapacity < 0) // 如果扩容后的容量让仍然不够存储，则将minCapacity作为新的数组的容量（addAll()添加集合时或使用到）
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elem = Arrays.copyOf(elem, newCapacity);  // 将原来的数组中的数据拷贝到新的数组中
    }
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }
}
